package com.cb2.algorithm.leetcode;

/**
 * <a href="https://leetcode.cn/problems/remove-nth-node-from-end-of-list/">删除链表的倒数第 N 个结点(Remove Nth Node From End of List)</a>
 * <p>给你一个链表，删除链表的倒数第 n 个结点，并且返回链表的头结点。 </p>
 * <p>
 * <b>示例</b>
 * <pre>
 * 示例 1：
 *      输入：head = [1,2,3,4,5], n = 2
 *      输出：[1,2,3,5]
 *
 * 示例 2：
 *      输入：head = [1], n = 1
 *      输出：[]
 *
 * 示例 3：
 *      输入：head = [1,2], n = 1
 *      输出：[1]
 * </pre>
 * </p>
 * <p>
 * <b>提示：</b>
 *     <ul>
 *          <li>链表中结点的数目为 sz</li>
 *          <li>1 <= sz <= 30</li>
 *          <li>0 <= Node.val <= 100</li>
 *          <li>1 <= n <= sz</li>
 *     </ul>
 * </p>
 *
 * @author c2b
 * @since 2023/10/13 13:36
 */
public class LC0019RemoveNthNodeFromEndOfList_M {

    static class Solution {
        public ListNode removeNthFromEnd(ListNode head, int n) {
            if (head == null) {
                return null;
            }
            // 给链表加个虚拟头，避免删除的是头节点
            ListNode dummyHead = new ListNode(-1, head);
            // 通过快慢指针，找到要删除节点的前一个节点
            ListNode slow = dummyHead;
            ListNode fast = dummyHead;
            // 快指针先走n步
            for (int i = 0; i < n; i++) {
                fast = fast.next;
            }
            // 快慢指针一起走，fast走到尾节点，slow刚好停在待删除结点的前一个
            while (fast.next != null) {
                slow = slow.next;
                fast = fast.next;
            }
            slow.next = slow.next.next;
            return dummyHead.next;
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        ListNode head1 = new ListNode(1);
        head1.next = new ListNode(2);
        head1.next.next = new ListNode(3);
        head1.next.next.next = new ListNode(4);
        head1.next.next.next.next = new ListNode(5);
        // 1 -> 2 -> 3 -> 5 -> null
        Printer.printListNode(solution.removeNthFromEnd(head1, 2));

        ListNode head2 = new ListNode(1);
        // null
        Printer.printListNode(solution.removeNthFromEnd(head2, 1));

        ListNode head3 = new ListNode(1);
        head3.next = new ListNode(2);
        // 2 -> null
        Printer.printListNode(solution.removeNthFromEnd(head3, 2));
    }
}